/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *	   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include<stdio.h>

#include "local_net_def.h"
#include "local_net_dlist.h"

Node_t *CreateDlist()    // 创建链表
{
    Node_t *head = malloc(sizeof(Node_t));
    head->data = NULL;
    head->before = head;
    head->after = head;
    return head;
}

int InsertHdlist(Node_t *head,const void *newdata,int size)    // 插入头部
{
    SYSERR(NULL, ==, head, "head is null", -1);
    SYSERR(NULL, ==, newdata, "newdata is null", -1);
    SYSERR(size, <=, 0,"size must >= 1", -1);
    
    Node_t *newNode = malloc(sizeof(Node_t));
    SYSERR(NULL, ==, newNode, "newNode is null", -1);
    newNode->data = malloc(size);
    if (!newNode->data) {
        free(newNode);
        return -1;
    }
    memcpy(newNode->data, newdata, size);

    newNode->after = head->after;
    head->after->before = newNode;
    newNode->before = head;
    head->after = newNode;
    return 0;
}

int InsertTdlist(Node_t *head,const void *newdata,int size)    //尾部插入
{
    SYSERR(NULL, ==, head, "head is null", -1);
    SYSERR(NULL, ==, newdata, "newdata is null", -1);
    SYSERR(size, <, 1, "size must >= 1", -1);

    Node_t *newNode = malloc(sizeof(Node_t));
    SYSERR(NULL, ==, newNode, "newNode is null", -1);
    newNode->data = malloc(size);  
    if (!newNode->data) {
        free(newNode->data);
        free(newNode);
        return -1;
    }
    memcpy(newNode->data, newdata, size);
    newNode->before = head->before;
    newNode->after = head;
    head->before->after = newNode;
    head->before = newNode;

    return 0;
}

Node_t *FindVdlist(Node_t *head,const void *value,CmpFun_t cmpFun)    //按值查找
{
    SYSERR(NULL, ==, head, "head is null", NULL);
    SYSERR(NULL, ==, value, "value is null", NULL);
    SYSERR(NULL, ==, cmpFun, "cmpFun is null", NULL);
    SYSERR(head->after, ==, head, "head is null", NULL);

    Node_t *temp = head->after;
    while(temp != head && NULL != temp->data)
    {
        if(!cmpFun(value, temp->data))
        {
            return temp;
        }
        temp = temp->after;
    }

    return NULL;
}

int DeleteHdlist(Node_t *head)    //头删
{
    SYSERR(NULL, ==, head, "head is null", -1);
    SYSERR(head->after, ==, head, "head is empty", -1);

    Node_t *temp = head->after;
    
    head->after = temp->after;
    temp->after->before = head;
    free(temp->data);
    free(temp);

    return 0;
}

void Printdlist(Node_t *head, PrintNodeFun_t printFun)
{
    SYSERR(NULL, ==, head, "head is null",);
    SYSERR(head->after, ==, head, "head is empty",);

    Node_t *temp = head->after;
    while(temp != head && NULL != temp->data)
    {
        LOG_I("print node info :");
        printFun(temp->data);
        temp = temp->after;
    }
    return;
}


void SelectSortdlist(Node_t *head, CmpFun_t cmpFun)    //选择排序
{
    SYSERR(NULL, ==, head, "head is null", );
    SYSERR(NULL, ==, cmpFun, "cmpFun is null", );
    // SYSERR(head->after, ==, head, "head is empty", );

    Node_t *inext = NULL;
    Node_t *jnext = NULL;
    void *tempNext = NULL;
    Node_t *min = NULL;

    for(inext = head->after; inext->after != head; inext = inext->after)
    {
        min = inext;
        for(jnext = inext->after; jnext != head; jnext = jnext->after)
        {
            if(cmpFun(jnext->data, min->data) > 0)
            {
                min = jnext;
            }
        }
        if(min != inext)
        {
            tempNext = min->data;
            min->data = inext->data;
            inext->data = tempNext;
        }
    }
}

int DeleteTdlist(Node_t *head)    //尾删
{
    SYSERR(NULL, ==, head, "head is null", -1);
    SYSERR(head->after, ==, head, "head is null", -1);

    Node_t *temp = head->before;
    if(temp != head)
    {
        head->before = temp->before;
        temp->before->after = head;
        free(temp->data);
        free(temp);
    }
    else
    {
        return -1;
    }

    return 0;
}

Node_t *DeleteVdlist(Node_t *head,const void *value,CmpFun_t cmpFun)    //按值删除
{
    SYSERR(NULL, ==, head, "head is null", NULL);
    SYSERR(NULL, ==, cmpFun, "cmpFun is null", NULL);
    SYSERR(head->after, ==, head, "head is null", NULL);
    
    Node_t *before = head;
    Node_t *temp = head->after;
    
    while(temp != head && temp->data != NULL)
    {
        if(!cmpFun(value,temp->data))
        {
            before->after = temp->after;
            temp->after->before = before;
            free(temp->data);
            free(temp);
            return before;
        }
        before = temp;
        temp = before->after;
    }

    return NULL;
}

int DestroyDlist(Node_t **head)    //清空整个链表
{
    SYSERR(NULL, ==, *head, "*head is null", -1);
    Node_t *temp =(*head)->after;

    while(temp != *head)
    {
        (*head)->after = temp->after;
        temp->after->before = *head;
        if(temp->data)
        {
            free(temp->data);
        }
        free(temp);
        
        temp=(*head)->after;
    }

    free(*head);
    (*head) = NULL;
    return 0;
}
